package fem2.jlinalg;

import inf.jlinalg.IMatrix;
import inf.jlinalg.IMatrixReadOnly;

import java.util.Arrays;

/**
 * Matrix class for diagonal matrix
 * 
 * @author hbui
 * 
 */
public class DiagonalMatrix implements IMatrix {

	private static final long serialVersionUID = 1L;

	protected double[] values;

	public DiagonalMatrix(double... values) {
		this.values = values;
	}

	public DiagonalMatrix(int n) {
		this.values = new double[n];
	}

	@Override
	public double get(int i, int j) {
		if (i != j) {
			return 0.0;
		} else {
			if (i >= values.length) {
				throw new Error("access outside of matrix range");
			}
			return values[i];
		}
	}

	@Override
	public int getColumnCount() {
		return values.length;
	}

	@Override
	public int getRowCount() {
		return values.length;
	}

	@Override
	public void add(int i, int j, double value) {
		if (i == j) {
			if (i >= values.length) {
				throw new Error("access outside of matrix range");
			}
			values[i] += value;
		}
	}

	@Override
	public void set(int i, int j, double value) {
		if (i == j) {
			if (i >= values.length) {
				throw new Error("access outside of matrix range");
			}
			values[i] = value;
		}
	}

	@Override
	public void assign(IMatrixReadOnly a) {
		int n = Math.min(a.getRowCount(), a.getColumnCount());
		values = new double[n];
		for (int i = 0; i < n; i++) {
			values[i] = a.get(i, i);
		}
	}

	@Override
	public Object clone() {
		return new DiagonalMatrix(values.clone());
	}

	/**
	 * set the diagonal to the specified value
	 * 
	 * @param C
	 * @param value
	 */
	public static void set(IMatrix C, double value) {
		if (C instanceof DiagonalMatrix) {
			Arrays.fill(((DiagonalMatrix) C).values, value);
		} else {
			int m = C.getRowCount();
			int n = C.getColumnCount();
			int p = Math.min(m, n);
			for (int i = 0; i < p; i++) {
				C.set(i, i, value);
			}
		}
	}
}
